package lzsrkpt.api.demo;

import java.io.File;
import java.io.FileInputStream;
import java.security.KeyStore;
import java.security.cert.CertificateException;
import java.security.cert.X509Certificate;

import javax.net.ssl.SSLContext;

import org.apache.http.client.methods.CloseableHttpResponse;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.conn.ssl.SSLConnectionSocketFactory;
import org.apache.http.conn.ssl.TrustStrategy;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClients;
import org.apache.http.ssl.SSLContexts;
import org.apache.http.util.EntityUtils;

import com.google.gson.Gson;

public class Request {
	/**
	 * 服务器地址
	 */
	private static final String SERVER_URL = "https://10.12.0.87/";
	/**
	 * 证书路径
	 */
	private static final String CERT_PATH = "F:\\Workplace\\openssl\\ca\\qfhssl\\lzsrkjkxxpt_client.p12";
	/**
	 * 证书密码
	 */
	private static final String CERT_PWD = "e3b3Y6YD7YjqAAaP";

	private String token;

	private static class SingletonHolder {
		static Request instance = new Request();
	}

	private Request() {
		getToken("admin", "admin");
	}

	public static Request getInstance() {
		return SingletonHolder.instance;
	}

	/**
	 * @param folderName 字典目录
	 * @param dicDesc    字典含义（中文说明）
	 * @param orgValue   字典值
	 * @return
	 * @throws Exception
	 */
	public ResponseBase dicUpLoad(String folderName, String dicDesc, String orgValue) {
		String url = SERVER_URL + "dataInterface/dicUpload?folderName=%s&dicDesc=%s&orgValue=%s&token=%s";
		String reqUrl = String.format(url, folderName, dicDesc, orgValue, token);
		String res = "";
		try {
			res = getRequestSSL(reqUrl, CERT_PATH, CERT_PWD);
			ResponseBase response = new Gson().fromJson(res, ResponseBase.class);
			if (response.getCode().equals(ResponseCode.RESPONSE_TOKEN_ERROR_CODE)) {
				return dicUpLoad(folderName, dicDesc, orgValue);
			} else {
				return response;
			}
		} catch (Exception ex) {
			System.out.println("请求返回：" + res);
			System.out.println(ex.getMessage());
			return null;
		}
	}

	public ResponseBase dataUpload(String businessName, String dataJson) {
		String url = SERVER_URL + "dataInterface/dataUpload?token=%s&businessName=%s&dataJson=%s";
		String reqUrl = String.format(url, token, businessName, java.net.URLEncoder.encode(dataJson));
		String res = "";
		try {
			res = getRequestSSL(reqUrl, CERT_PATH, CERT_PWD);
			ResponseBase response = new Gson().fromJson(res, ResponseBase.class);
			if (response.getCode().equals(ResponseCode.RESPONSE_TOKEN_ERROR_CODE)) {
				return dataUpload(businessName, dataJson);
			} else {
				return response;
			}
		} catch (Exception ex) {
			System.out.println("请求返回：" + res);
			System.out.println(ex.getMessage());
			return null;
		}
	}

	/**
	 * @param user 用户
	 * @param pwd  密码
	 * @return
	 */
	private void getToken(String user, String pwd) {
		String url = SERVER_URL + "interface/login?account=%s&password=%s";
		String reqUrl = String.format(url, user, pwd);
		String res = "";
		try {
			res = this.getRequestSSL(reqUrl, CERT_PATH, CERT_PWD);
			ResponseToken response = new Gson().fromJson(res, ResponseToken.class);
			if (response.getCode().equals(ResponseCode.RESPONSE_SUCCESS_CODE)) {
				this.token = response.getToken();
			} else {
				System.out.println(response);
			}
		} catch (Exception ex) {
			System.out.println("请求返回：" + res);
			System.out.println(ex.getMessage());
		}
	}

	/**
	 * @param url      请求地下
	 * @param certPath 证书路径
	 * @param certPwd  证书密码
	 * @return
	 * @throws Exception
	 */
	private String getRequestSSL(String url, String certPath, String certPwd) throws Exception {
		KeyStore keyStore = KeyStore.getInstance("PKCS12");
		keyStore.load(new FileInputStream(new File(certPath)), certPwd.toCharArray());
		SSLContext sslcontext = SSLContexts.custom().loadTrustMaterial(new TrustStrategy() {
			public boolean isTrusted(X509Certificate[] chain, String authType) throws CertificateException {
				return true;
			}
		}).loadKeyMaterial(keyStore, certPwd.toCharArray()).build();
		SSLConnectionSocketFactory sslConnectionSocketFactory = new SSLConnectionSocketFactory(sslcontext,
				new String[] { "TLSv1.2" }, null, SSLConnectionSocketFactory.getDefaultHostnameVerifier());
		CloseableHttpClient httpclient = HttpClients.custom().setSSLSocketFactory(sslConnectionSocketFactory).build();
		HttpGet httpget = new HttpGet(url);
		CloseableHttpResponse response = httpclient.execute(httpget);
		return EntityUtils.toString(response.getEntity(), "UTF-8");
	}
}
